package com.soulkun.smarthome.logic.creator

import com.soulkun.smarthome.logic.Constant
import com.soulkun.smarthome.logic.ServiceCreator
import com.soulkun.smarthome.logic.dto.*
import com.soulkun.smarthome.logic.enum.ErrorCodeEnum
import com.soulkun.smarthome.logic.exception.ApiException
import com.soulkun.smarthome.logic.model.DeviceModel
import com.soulkun.smarthome.logic.model.FamilyModel
import com.soulkun.smarthome.logic.model.RoomModel
import com.soulkun.smarthome.logic.model.UserModel
import com.soulkun.smarthome.logic.service.*
import kotlinx.coroutines.suspendCancellableCoroutine
import retrofit2.*
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

object ApiServiceCreator {

    //协程挂起，Call返回数据后处理核心逻辑
    private suspend fun <T> Call<T>.await(): T {
        return suspendCancellableCoroutine {
            it.invokeOnCancellation {
                cancel()
            }
            enqueue(object : Callback<T> {
                override fun onFailure(call: Call<T>, t: Throwable) {
                    it.resumeWithException(t)
                }

                override fun onResponse(call: Call<T>, response: Response<T>) {
                    val body = response.body()
                    if (body != null) it.resume(body)
                    else it.resumeWithException(
                        ApiException(
                            ErrorCodeEnum.HttpError.code,
                            "返回数据为空"
                        )
                    )
                }
            })
        }
    }

    private val userService = ServiceCreator.apiRetrofitCreator<ApiUserService>(Constant.BASE_URL_API)
    private val familyService = ServiceCreator.apiRetrofitCreator<ApiFamilyService>(Constant.BASE_URL_API)
    private val roomService = ServiceCreator.apiRetrofitCreator<ApiRoomService>(Constant.BASE_URL_API)
    private val deviceService = ServiceCreator.apiRetrofitCreator<ApiDeviceService>(Constant.BASE_URL_API)
    private val weatherService = ServiceCreator.commonRetrofitCreator<CaiyunWeatherService>("${Constant.BASE_URL_WEATHER}/${Constant.API_KEY_WEATHER}/")

    /**
     * 用户方面的逻辑
     */
    suspend fun login(requestBody: UserModel) = userService.login(requestBody).await()
    suspend fun register(requestBody: UserModel) = userService.register(requestBody).await()
    suspend fun logout() = userService.logout().await()
    suspend fun getUserInfo() = userService.getUserInfo().await()
    suspend fun fillUserInfo(requestBody: UserModel) = userService.modifyUserNickname(requestBody).await()
    suspend fun checkAvailableUserName(username: String) = userService.checkAvailableUserName(username).await()
    suspend fun getAlertMessageList() = userService.getAlertMessageList().await()
    suspend fun getFamilyMessageList() = userService.getFamilyMessageList().await()

    /**
     * 家庭方面的逻辑
     */
    suspend fun createFamily(requestBody: FamilyRoomDTO) = familyService.createFamily(requestBody).await()
    suspend fun generateFamilyInvitation(requestBody: FamilyModel) = familyService.generateFamilyInvitation(requestBody).await()
    suspend fun getFamilyDetailInfo(requestBody: FamilyModel) = familyService.getFamilyDetailInfo(requestBody).await()
    suspend fun modifyFamilyName(requestBody: FamilyModel) = familyService.modifyFamilyName(requestBody).await()
    suspend fun modifyFamilyLocation(requestBody: FamilyModel) = familyService.modifyFamilyLocation(requestBody).await()
    suspend fun joinFamily(requestBody: FamilyInvitationDTO) = familyService.joinFamily(requestBody).await()
    suspend fun getFamilyNameList() = familyService.getFamilySimpleInfoList().await()
    suspend fun getRoomDeviceList(requestBody: FamilyModel) = familyService.getRoomDeviceList(requestBody).await()
    suspend fun deleteFamily(requestBody: FamilyModel) = familyService.deleteFamily(requestBody).await()
    suspend fun setFamilyUserRole(requestBody: FamilyUserRoleDTO) = familyService.setFamilyUserRole(requestBody).await()
    suspend fun deleteFamilyUser(requestBody: FamilyUserRoleDTO) = familyService.deleteFamilyUser(requestBody).await()
    suspend fun getRoomDeviceCommandList(requestBody: FamilyModel) = familyService.getRoomDeviceCommandList(requestBody).await()
    suspend fun getFamilyRoleList() = familyService.getFamilyRoleList().await()
    /**
     * 房间方面的逻辑
     */
    suspend fun addRoom(requestBody: RoomModel) = roomService.addRoom(requestBody).await()
    suspend fun deleteRoom(requestBody: RoomModel) = roomService.deleteRoom(requestBody).await()
    suspend fun modifyRoomName(requestBody: RoomModel) = roomService.modifyRoomName(requestBody).await()
    /**
     * 设备方面的逻辑
     */
    suspend fun addDevice(requestBody: DeviceModel) = deviceService.addDevice(requestBody).await()
    suspend fun deleteDevice(requestBody: DeviceModel) = deviceService.deleteDevice(requestBody).await()
    suspend fun modifyDeviceName(requestBody: DeviceModel) = deviceService.modifyDeviceName(requestBody).await()
    suspend fun getDeviceData(requestBody: DeviceModel) = deviceService.getDeviceData(requestBody).await()
    suspend fun getDeviceAttributeList(requestBody: DeviceModel) = deviceService.getDeviceAttributeList(requestBody).await()
    suspend fun getDeviceCommandList(requestBody: DeviceModel) = deviceService.getDeviceCommandList(requestBody).await()
    suspend fun postDeviceCommand(requestBody: DeviceCommandPostDTO) = deviceService.postDeviceCommand(requestBody).await()
    suspend fun getDeviceDataHistory(requestBody: DeviceDataHistoryRequestDTO) = deviceService.getDeviceDataHistory(requestBody).await()
    suspend fun getDeviceCommandHistory(requestBody: DeviceCommandHistoryRequestDTO) = deviceService.getDeviceCommandHistory(requestBody).await()
    /**
     * 天气方面的逻辑
     */
    suspend fun getWeatherRealtime(longitude: Double, latitude: Double) = weatherService.getWeatherRealtime(longitude, latitude).await()
    suspend fun getWeatherMinutely(longitude: Double, latitude: Double) = weatherService.getWeatherMinutely(longitude, latitude).await()

}